package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.zzyl.constant.SuperConstant;
import com.zzyl.dto.ResourceDto;
import com.zzyl.entity.Resource;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.ResourceMapper;
import com.zzyl.service.ResourceService;
import com.zzyl.utils.NoProcessing;
import com.zzyl.utils.StringUtils;
import com.zzyl.vo.ResourceVo;
import com.zzyl.vo.TreeItemVo;
import com.zzyl.vo.TreeVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ResourceServiceImpl implements ResourceService {

    @Autowired
    private ResourceMapper resourceMapper;

    /**
     * 资源列表查询
     * @param resourceDto
     * @return
     */
    @Override
    public List<ResourceVo> list(ResourceDto resourceDto) {
        //1.
        ResourceVo bean = BeanUtil.toBean(resourceDto, ResourceVo.class);
        //2.
        List<ResourceVo> list = resourceMapper.list(bean);

        return list;
    }

    /**
     * 资源树形
     * @param resourceDto
     * @return
     */
    @Override
    public TreeVo resourceTreeVo(ResourceDto resourceDto) {
        //1.创建返回数据的对象
        TreeVo treeVo = new TreeVo();

        //2.创建根节点 并构建目录关系
        TreeItemVo root = new TreeItemVo();
        root.setId(SuperConstant.ROOT_PARENT_ID);
        root.setLabel("智慧养老院");

        List<TreeItemVo> list = new ArrayList<>();
        list.add(root);
        treeVo.setItems(list);

        //3.通过条件查询所有的菜单节点
        ResourceVo bean = BeanUtil.toBean(resourceDto, ResourceVo.class);
        bean.setParentResourceNo(NoProcessing.processString(SuperConstant.ROOT_PARENT_ID));
        bean.setDataState(SuperConstant.DATA_STATE_0);
        bean.setResourceType(SuperConstant.MENU);
        List<ResourceVo> listResource = resourceMapper.list(bean);

        //4.通过节点查找所有的一级目录 并构建关系
        /*List<ResourceVo> firstTree = new ArrayList<>();
        for (ResourceVo resource : listResource) {
            if (resource.getParentResourceNo().equals(root.getId())){
                firstTree.add(resource);
            }
        }*/  // 效率不高

            //.stream().filter(r->{}) 用于过滤，返回为boolean类型，
        List<ResourceVo> firstTree = listResource.stream().filter(r -> {
            if (r.getParentResourceNo().equals(root.getId())) {
                return true;
            } else {
                return false;
            }
        }).collect(Collectors.toList());

        List<TreeItemVo> firstTreeList = firstTree.stream().map(r -> {
            TreeItemVo vo = new TreeItemVo();
            vo.setId(r.getResourceNo());
            vo.setLabel(r.getResourceName());

            return vo;
        }).collect(Collectors.toList());

        root.setChildren(firstTreeList);

        //5.遍历每一个一级目录 然后找找对应的一级目录下的二级目录 并构建关系
        root.getChildren().stream().map(first ->{
            List<ResourceVo> secondTree = listResource.stream().filter(r -> {
                if (r.getParentResourceNo().equals(first.getId())) {
                    return true;
                } else {
                    return false;
                }
            }).collect(Collectors.toList());

            List<TreeItemVo> secondTreeList = secondTree.stream().map(r -> {
                TreeItemVo vo = new TreeItemVo();
                vo.setId(r.getResourceNo());
                vo.setLabel(r.getResourceName());

                return vo;
            }).collect(Collectors.toList());

            first.setChildren(secondTreeList);

            return first; //无意义
        }).collect(Collectors.toList());

        //6.遍历每一个二级目录 然后找找对应的二级目录下的三级目录 并构建关系
        root.getChildren().stream().map(first -> {
            first.getChildren().stream().map(second -> {
                List<ResourceVo> thirdTree = listResource.stream().filter(resourceVo -> {
                    if (resourceVo.getParentResourceNo().equals(second.getId())) {
                        return true;
                    } else {
                        return false;
                    }
                }).collect(Collectors.toList());

                List<TreeItemVo> thirdTreeList = thirdTree.stream().map(resourceVo -> {
                    TreeItemVo vo = new TreeItemVo();
                    vo.setId(resourceVo.getResourceNo());
                    vo.setLabel(resourceVo.getResourceName());

                    return vo;
                }).collect(Collectors.toList());

                second.setChildren(thirdTreeList);

                return second;
            }).collect(Collectors.toList());
            return first;
        }).collect(Collectors.toList());

        //7.返回结果
        return treeVo;
    }

    /**
     * 新增资源菜单
     * @param resourceDto
     */
    @Override
    public void createResource(ResourceDto resourceDto){
        //1.创建Vo对象 并把dto的数据拷贝到Vo
        ResourceVo bean = BeanUtil.toBean(resourceDto, ResourceVo.class);

        //2.查询父菜单的数据 然后设置子菜单的状态(判断父菜单是否存在)
        String parent = resourceMapper.searchByParentNo(bean.getParentResourceNo());
        if(parent == null){
            throw new BaseException(BasicEnum.PARENT_MENU_NO_EXIST);
        }
        bean.setDataState(parent);

        //3.设置当前新增菜单的编码
        bean.setResourceNo(createResourceNo(resourceDto));

        //4.补充通用字段
        bean.setCreateBy(1671362878457892866L);
        bean.setCreateTime(LocalDateTime.now());
        bean.setUpdateTime(LocalDateTime.now());
        bean.setLabel(bean.getRequestPath().replaceAll("/",":"));

        //5.保存到数据库
        resourceMapper.createResource(bean);

    }

    /**
     * 设置当前新增菜单的编码
     * @return
     */
    private String createResourceNo(ResourceDto resourceDto) {
        //1.如果创建的不是按钮 且成绩高于3层 抛出异常
        if (!StringUtils.isEmpty(resourceDto.getParentResourceNo()) && SuperConstant.MENU.equals(resourceDto.getSortNo())){
            //判断层级
            if(NoProcessing.processString(resourceDto.getParentResourceNo()).length() > 12){
                throw new BaseException(BasicEnum.RESOURCE_DEPTH_UPPER_LIMIT);
            }
        }

        //2.查询父的resourceNo下的所有的子菜单
        ResourceVo resourceVo = new ResourceVo();
        resourceVo.setParentResourceNo(resourceDto.getParentResourceNo());
        List<ResourceVo> list = resourceMapper.list(resourceVo);

        //3.判断子菜单是否存在 如果不存在 则直接在父resourceNo的出具上添加001
        if (list == null || list.size() == 0){
            //直接在父resourceNo的出具上添加001
            return NoProcessing.createNo(resourceDto.getParentResourceNo(),false);
        }else {
            //4.如果存在子菜单 这找到最大的id 然后+1
            Long maxVo = list.stream().map(it -> Long.parseLong(it.getResourceNo())).max(Comparator.comparing(i -> i)).get();
            return NoProcessing.createNo(maxVo.toString(),true);
        }
    }

    /**
     * 修改资源
     * @param resourceDto
     */
    @Override
    public void updateResource(ResourceDto resourceDto) {
        //1.获取path
        List<ResourceVo> listByOne = resourceMapper.list(BeanUtil.toBean(resourceDto, ResourceVo.class));
        //2.遍历集合
        listByOne.stream().map(resourceVo -> {
            //3.进行判断，是否修改
            if (resourceVo.getRequestPath().equals(resourceDto.getRequestPath())){
                //3.1未修改，直接修改资源
                //1.
                Resource bean = BeanUtil.toBean(resourceDto, Resource.class);
                //2.
                bean.setUpdateTime(LocalDateTime.now());
                //3.
                resourceMapper.updateResource(bean);
                return true;
            }else {
                //3.2 已修改 获取全部path 进行进一步判断
                List<ResourceVo> list = resourceMapper.list(new ResourceVo());
                //3.3 过滤条件
                List<ResourceVo> path = list.stream().filter(vo -> {
                    if (vo.getRequestPath().equals(resourceDto.getRequestPath())) {
                        return true;
                    } else {
                        return false;
                    }
                }).collect(Collectors.toList());
                //3.4 进行判断
                if (path.size()==0){
                    //3.4.1 未冲突 直接修改
                    //1.
                    Resource bean = BeanUtil.toBean(resourceDto, Resource.class);
                    //2.
                    bean.setUpdateTime(LocalDateTime.now());
                    //3.
                    resourceMapper.updateResource(bean);

                    return true;
                }else {
                    //3.4.2 冲突 抛出异常
                    throw new BaseException(BasicEnum.MENU_PATH_DUPLICATE_EXCEPTION);
                }
            }
        }).collect(Collectors.toList());


    }

    /**
     * 启用与禁用
     * @param resourceDto
     */
    @Override
    public void updateOfDataState(ResourceDto resourceDto) {
        //1.
        String dataParent = resourceMapper.searchByParentNo(resourceDto.getParentResourceNo());
        //2.
        if (dataParent != null && Integer.parseInt(dataParent) == 0){

            String data = resourceMapper.searchByParentNo(resourceDto.getResourceNo());
            //0.
            if (data == null || data == ""){
                throw new BaseException(BasicEnum.MENU_DISTRIBUTED);
            }
            //1.
            Resource bean = BeanUtil.toBean(resourceDto, Resource.class);
            //2.
            bean.setUpdateTime(LocalDateTime.now());
            //3.
            resourceMapper.updateResource(bean);
        }else {
            throw new BaseException(BasicEnum.PARENT_MENU_DISABLE);
        }
    }

    /**
     * 删除菜单
     * @param menuId
     */
    @Override
    public void deleteByMenuId(Long menuId) {
        //1.
        String resourceNo = menuId.toString();
        //2.获取parentResourceNo相同的数据
        List<ResourceVo> list = resourceMapper.list(ResourceVo.builder().parentResourceNo(resourceNo).build());
        //3.进行判断，若存在父no，则抛出异常
        if (list.size() !=0){
            throw new BaseException(BasicEnum.MENU_SON_DELETE);
        }else {
            resourceMapper.deleteByMenuId(resourceNo);
        }
    }
}
